package fdq.service;

import fdq.entity.Animal;
import fdq.entity.AnimalSet;
import fdq.entity.Feature;
import fdq.mapper.AnimalMapper;
import fdq.mapper.FeatureMapper;
import fdq.utils.SqlSessionGet;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainServiceImp implements MainService{
    private final SqlSessionGet sqlSessionGet = new SqlSessionGet();
    private final SqlSession sqlSession = sqlSessionGet.getSqlsession();
    private FeatureMapper featureMapper = sqlSession.getMapper(FeatureMapper.class);
    private AnimalMapper animalMappermapper = sqlSession.getMapper(AnimalMapper.class);
    @Override
    public AnimalSet createAnimalSet(ArrayList<Feature> feature) {
        ArrayList<Animal> animals = new ArrayList<>();
        //特征找动物
        for(Feature f: feature){
            ArrayList<Animal> animalArrayList = animalMappermapper.selectAnimalsByFid(f.getFid());
            for(Animal a : animalArrayList){
                animals.add(a);
            }
        }

        AnimalSet animalSet = new AnimalSet(animals);
        return animalSet;
    }

    //根据特征集中的特征推理出其他特征
    @Override
    public ArrayList<Feature> expandFeatures(ArrayList<Feature> featureArrayList) {
        //因为在遍历list数组时向数组添加元素会报错，所以创建一个list数组用于存放将要添加的元素，最后返回该数组
       ArrayList<Feature> returnList = new ArrayList<>();
       //将原数组中的元素赋值给要返回的数组
        for(Feature f : featureArrayList){
            returnList.add(f);
        }

        for(Feature featureItem : featureArrayList){
            //判断该特征能够推理出的全部特征
            //多前提推出的结论
            ArrayList<Feature> featuresByConditions = featureMapper.selectFeaturesByFeatures(featureItem.getFid());
            System.out.println("当前分析的特征是"+featureItem.getFid());
            for(Feature f : featuresByConditions){
                System.out.println("该前提能推出的结论有"+f.getFid()+"---");
            }
            //单一前提推出的结论
            ArrayList<Feature> featuresByOneCondition = featureMapper.selectFeaturesByOneFeature(featureItem.getFid());

            //判断哪些特征是可以被推理出来的（给的特征集包含推理所需要的特征）
            for(Feature featureProdeced : featuresByConditions){
                //condition:某一个结论所需的全部前提
                System.out.println("当前分析的结论是："+featureProdeced.getFid());
                ArrayList<Feature> conditions = featureMapper.selectFeaturesByResult(featureProdeced.getFid());
                for(Feature f1 : conditions){
                    System.out.println("该结论需要的前提有："+f1.getFid());
                }
                System.out.println("当前特征集有：");
                for(Feature f2 : returnList){
                    System.out.println(f2.getFid());
                }
                //判断该前提是否在特征集中
                //在这里需要传参数时需要
                boolean conditionsInside = Feature.featureInside(conditions, returnList);

                //如果全部前提都在特征集中将该特征加入特征集
                if(conditionsInside){
                    //判断特征是否已经在特征集中
                    boolean featureInside = Feature.featureInside(featureProdeced, returnList);
                    if(!featureInside){
                        returnList.add(featureProdeced);
                    }
                }

            }

            //单特征结论推理
            for(Feature featureProdeced: featuresByOneCondition){
                //conditions:所有能够推出该结论的单条件
                ArrayList<Feature> conditions = featureMapper.selectOneFeatureByResult(featureProdeced.getFid());
                //判断该前提是否在特征集中
                for(Feature condition : conditions){
                    boolean conditionsInside = Feature.featureInside(condition, returnList);
                    if(conditionsInside){
                        //判断特征是否已经在特征集中
                        boolean featureInside = Feature.featureInside(featureProdeced, returnList);
                        if(!featureInside){
                            returnList.add(featureProdeced);
                        }
                    }
                }
            }

        }

        //转换为数组类型返回
        return  returnList;
    }

    @Override
    public Feature[] selectAllFeatures() {
        Feature[] features = featureMapper.selectAllFeatures();
        return features;
    }

    @Override
    public ArrayList<Feature> selectFeaturesFromSet(AnimalSet animalSet) {
        ArrayList<Feature> returnList = new ArrayList<>();
        for(Animal a : animalSet.getAnimalList()){
            ArrayList<Feature> featureByAnimalList = featureMapper.selectFeatureByAnimal(a.getAid());
            for(Feature f : featureByAnimalList){
                returnList.add(f);
            }
        }
        return returnList;
    }


    @Override
    public AnimalSet getAllAnimal() {
        ArrayList<Animal> animalArrayList = animalMappermapper.selectAllAnimal();
        AnimalSet animalSet = new AnimalSet(animalArrayList);
        return animalSet;
    }
}
